#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include "logger.h"
#include "buffer.h"

int fd;
struct buffer_st buffer;
int session_tracker = 0;
int log_level = INFO;	//current level of logging, start with info

#define LOG_LEVEL_NAME(l_level) #l_level
char *log_lname[] = {
	LOG_LEVEL_NAME(INFO),
	LOG_LEVEL_NAME(WARNING),
	LOG_LEVEL_NAME(ERROR)
};

int log_init(char *filename, unsigned int buf_size) {
		fd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
		if (fd == -1) {
			perror("failed to open log file");
			return -1;
		}
		if (buffer_create(&buffer, buf_size, fd) == -1) {
			perror("failed to create buffer");
			close(fd);
			return -1;
		};
		return 1;	//intialize successfull; 
}

void log_print(int level, char *filename, int line, char* fmt, ...) {
	va_list list;
	if (level < log_level) 
			return;

	char *lg_info, *message;
	int size = 100;	//i hope 100 bytes for one message will be enough

	if ((lg_info = (char*)malloc(size)) == NULL || (message = (char*)malloc(size)) == NULL) {
		free(lg_info);
		free(message);
		return;
	}

    time_t event_time;
	int message_length = sprintf(lg_info, "%s : [%s]\t [%s][line: %d]\t", 
			ctime(&event_time), log_lname[level] ,filename, line);
	if (buffer_write_message(&buffer, lg_info, message_length) == -1) {
		return;
	}

	va_start(list, fmt);
		message_length = sprintf(message, fmt, list);
		if (buffer_write_message(&buffer, message, message_length) == -1) {
		return;
	}
	va_end(list);
	free(lg_info);
	free(message);
}

void log_finalize() {
	buffer_flush(&buffer);
	buffer_free(&buffer);
	close(fd);
}

void set_log_level(int log_nlevel) {
	if (log_nlevel >= 0 && log_nlevel < MAX_LOG_LEVEL) {
		log_level = log_nlevel;
	} else {
		log_print(WARNING, __FILE__, __LINE__, "Unknown logging level(current [%s])",log_lname[log_level]);
	}
}
